using System;
using Amazon.ECS.Model;

namespace RomanJendrusz.Amazon.ETL.Messages.MessageMappers
{
    public abstract class MessageMapper<Request, AWSRequest, AwsResponse>: IMessageMapper<AWSRequest, AwsResponse>
        where Request:AmazonRequest
    {
        private Guid correlationId;
        private bool correlationIdWasSet;
        protected Guid CorrelationId
        {
            get
            {
               if(!correlationIdWasSet)
               {
                   throw new InvalidOperationException(
                       "before a mapper can map the response, he needs to map the request");
               }
                return correlationId;
            }
        }

        public abstract AWSRequest MapToAwsRequest(Request request);

        public AWSRequest MapToAwsRequest(AmazonRequest request)
        {
            correlationIdWasSet = true;
            correlationId = request.CorrelationId;
            return MapToAwsRequest((Request) request);
        }

        public abstract AmazonResponse MapToAmazonResponse(AwsResponse awsResponse);

        protected Item GetRequestItem(ItemLookupResponse from, int atPosition)
        {
            if (from == null) throw new ArgumentNullException("from");
            if (from.IsSetItems() == false)
            {
                throw new ArgumentException("There is no response Item");
            }
            var requestItem = from.Items[atPosition];
            if (requestItem.IsSetItem() == false)
            {
                throw new InvalidOperationException("There is no Book that can be readed from the response");
            }
            from.Items.RemoveAt(atPosition);
            try
            {
                return requestItem.Item[0];
            }
            catch (IndexOutOfRangeException ex)
            {
                throw new InvalidOperationException("The book item was noot found", ex);
            }
        }
    }
}